/* Copyright 2009 Requirements Management System 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mags.remas.view;

import java.util.List;   
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.mags.common.EngineContext;
import org.mags.remas.control.commons.Cloner;
import org.mags.remas.model.entity.EntityRelationship;
import org.mags.remas.model.entity.ViewType;
import org.mags.remas.view.commons.RelationshipEditorBase;
import org.mags.remas.view.widgets.ButtonLinkCellEditor;
import org.mags.remas.view.widgets.RelationshipTreeViewer;
import org.mags.remas.view.widgets.RelationshipTreeViewerListener;
import org.mags.remas.view.widgets.TreeActionTransmitter;

/**
 * 
 * @author Mario Gaitan
 *
 */
public abstract class AbstractSubentitiesEditor extends RelationshipEditorBase 
	implements RelationshipTreeViewerListener, ICellModifier {
	private int oldTextHeight = -1;
	private int oldTextWidth = -1;
	private CellEditor[] editors = new CellEditor[3];
	private RelationshipTreeViewer treeViewer;
	protected ViewType viewType = EngineContext.getDataContext().getEntityProviderFactory().getViewTypeProvider().getEDITVIEW();
	
	@Override
	public void dispose() {
		super.dispose();
		if(treeViewer!=null)
			TreeActionTransmitter.getInstance().remove(treeViewer);
	}
	public RelationshipTreeViewer getTreeViewer() {
		return treeViewer;
	}
	private void resizeAreaText(Text text) {
		String t = text.getText();
		GC gc = new GC(text);
		Point size = gc.textExtent(t);
		Point parentSize = treeViewer.getTree().getSize();
		int w = text.getBounds().width;
		int h = text.getBounds().height;
		if(size.y>=oldTextHeight&&size.y<=parentSize.y-text.getBounds().y-25)
			h = size.y+15;
		if(size.x>=oldTextWidth&&size.x<=parentSize.x-text.getBounds().x-25)
			w = size.x+15;
		text.setSize(w, h);
	}
	public void createPartControl(Composite parent) {
		treeViewer = new RelationshipTreeViewer(parent, SWT.FULL_SELECTION, viewType);
		TreeActionTransmitter.getInstance().add(treeViewer);
		treeViewer.setShowCursor(true);
		treeViewer.setAllowShowColumn(true);
		treeViewer.setIntercalateColor(true);
		treeViewer.getTree().setHeaderVisible(true);
		treeViewer.getTree().setLinesVisible(true);
		treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
		treeViewer.addRelationshipTreeViewerListener(this);
		super.getSite().setSelectionProvider(treeViewer);
		TreeColumn column = new TreeColumn(treeViewer.getTree(), SWT.LEFT);
		column.setText("name");
		column.setWidth(200);
		column.setResizable(true);
		column.setToolTipText("name of item");
		column.setMoveable(false);
		
		column = new TreeColumn(treeViewer.getTree(), SWT.LEFT|SWT.MULTI|SWT.V_SCROLL);	
		column.setText("description");
		column.setWidth(300);
		column.setResizable(true);
		column.setToolTipText("description");
		column.setMoveable(false);

		column = new TreeColumn(treeViewer.getTree(), SWT.LEFT);	
		column.setText("link");
		column.setWidth(300);
		column.setResizable(true);
		column.setToolTipText("link");
		column.setMoveable(false);	
		
		treeViewer.setColumnProperties(new String[]{"name", "description", "link"});
		treeViewer.setCellModifier(this);

		editors[0] = new TextCellEditor(treeViewer.getTree(), SWT.BORDER);
		GridData gridDataDescription = new GridData();
		gridDataDescription.horizontalAlignment = SWT.FILL;
		gridDataDescription.grabExcessHorizontalSpace = true;
		gridDataDescription.verticalAlignment = SWT.FILL;	
		gridDataDescription.verticalSpan = 4;
		gridDataDescription.grabExcessVerticalSpace=true;		
		editors[1] = new TextCellEditor(treeViewer.getTree(), SWT.MULTI|SWT.BORDER);
		final Text text = (Text)editors[1].getControl();
		text.setTextLimit(510);		
		editors[1].getControl().setLayoutData(gridDataDescription);
		editors[1].getControl().addFocusListener(new FocusListener() {
			@Override
			public void focusGained(FocusEvent e) {
				oldTextHeight = text.getSize().y;
				oldTextWidth = text.getSize().x;
				resizeAreaText(text);
			}
			@Override
			public void focusLost(FocusEvent e) {
			}
		});
		editors[1].getControl().addKeyListener(new KeyListener() {
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.keyCode==SWT.TAB) {
					AbstractSubentitiesEditor.this.editors[1].getControl().traverse(SWT.TRAVERSE_TAB_NEXT);
					e.doit = false;
				}
				resizeAreaText(text);
			}
			@Override
			public void keyReleased(KeyEvent e) {
			}
		});		
		editors[2] = new ButtonLinkCellEditor(treeViewer.getTree(), SWT.BORDER);
		treeViewer.setCellEditors(editors);
	}
	public void setFocus() {		
		treeViewer.getTree().setFocus();
	}	
	public boolean canModify(Object element, String property) {
		return true;
	}
	public Object getValue(Object element, String property) {
		final EntityRelationship entityRelationship = (EntityRelationship)element;
		if(property.equalsIgnoreCase("name"))
			return entityRelationship.getEntity().getName();
		else if(property.equalsIgnoreCase("description"))
			return (entityRelationship.getEntity().getDescription()!=null)?entityRelationship.getEntity().getDescription():"";
		else if(property.equalsIgnoreCase("link")) {
			EntityRelationship clone = Cloner.clone(entityRelationship);
			return clone;
		}
		return null;
	}
	public void modify(Object element, String property, Object value) {
		TreeItem treeItem = (TreeItem)element;
		EntityRelationship entityRelationship = (EntityRelationship)treeItem.getData();
		if(property.equalsIgnoreCase("name")) {
			if(value!=null&&((String)value).equals(entityRelationship.getEntity().getName()))
				return ;
		}
		else if(property.equalsIgnoreCase("description")) {
			if(value!=null&&((String)value).equals(entityRelationship.getEntity().getDescription()))
				return ;
		}
		else if(property.equalsIgnoreCase("link")) {
			long oldLinkId = (entityRelationship.getLink()==null)?0:entityRelationship.getLink().getEntityRelationshipId();
			long linkId = (((EntityRelationship)value).getLink()==null)?0:((EntityRelationship)value).getLink().getEntityRelationshipId();
			if(oldLinkId==linkId)
				return ;
		}
		update(entityRelationship, property, value);
	}
	
	public abstract void update(EntityRelationship entityRelationship, String property, Object value);
	public abstract boolean dragAndDrop(EntityRelationship target, List<EntityRelationship> elementsDroped);
	public abstract void doubleClick(EntityRelationship first);
	public void select(EntityRelationship first, List<EntityRelationship> elements) {
		PropertiesView propertiesView = (PropertiesView)getSite().getPage().findView(PropertiesView.ID);
		if(propertiesView!=null) {
			propertiesView.setEntityRelationship(first);
			propertiesView.refresh();					
		}				
	}
}
